package com.xbongbong.paas.connection.connector.service;

import com.alibaba.fastjson.JSONObject;
import com.xbongbong.paas.connection.pojo.connector.ActionBasePojo;
import com.xbongbong.paas.domain.entity.ext.PaasFormDataEntityExt;
import com.xbongbong.paas.elasticsearch.util.EsHelper;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.IndexTypeEnum;
import com.xbongbong.paas.enums.PlatFormEnum;
import com.xbongbong.paas.manager.feign.ConnectionUserFeignClient;
import com.xbongbong.paas.pojo.dto.UserInfoDTO;
import com.xbongbong.paas.pojo.vo.UserInfoVO;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.wrap.UserVO;
import com.xbongbong.paas.toolbox.wrap.XbbResponse;
import com.xbongbong.pro.enums.SaasMarkEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.ContractEnum;
import com.xbongbong.saas.enums.business.CustomerManagementEnum;
import com.xbongbong.saas.enums.business.SalesOpportunityEnum;
import com.xbongbong.saas.model.IndexTypeModel;
import com.xbongbong.sys.enums.ConnectorActionEnum;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.i18n.LocaleContextHolder;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Objects;

import static org.elasticsearch.index.query.QueryBuilders.boolQuery;
import static org.elasticsearch.index.query.QueryBuilders.termQuery;

public abstract class AbstractStandardConnector {
    private static final Logger LOG = LoggerFactory.getLogger(AbstractStandardConnector.class);

    @Resource
    private ConnectionUserFeignClient connectionUserFeignClient;
    @Resource
    private EsHelper esHelper;
    @Resource
    private IndexTypeModel indexTypeModel;

    /**
     * 接收连接器数据变更回调
     * @param jsonObject
     * @throws XbbException
     */
    public void action(JSONObject jsonObject) throws XbbException {
        ActionBasePojo actionBasePojo = jsonObject.toJavaObject(ActionBasePojo.class);
        String action = actionBasePojo.getDdDataAction();
        ConnectorActionEnum connectorActionEnum = ConnectorActionEnum.getByAlias(action);
        LOG.info(connectorActionEnum.getAlias());
        switch (connectorActionEnum) {
            case ADD:
            case UPDATE:
                saveStandard(jsonObject);
                break;
            case DELETE:
                deleteStandard(jsonObject);
                break;
            default:
                break;
        }
    }

    public void saveStandard(JSONObject jsonObject) throws XbbException {
        ActionBasePojo actionBasePojo = jsonObject.toJavaObject(ActionBasePojo.class);
        String corpid = actionBasePojo.getDdDataCorpId();
        String operateUserId = actionBasePojo.getOperateUserId();
        UserVO userVo = getUserVO(corpid, operateUserId);
        PaasFormDataEntityExt paasFormData = getEntity(corpid, jsonObject);
        if (Objects.isNull(paasFormData)) {
            addStandard(corpid, userVo, jsonObject);
        } else {
            //编辑
            updateStandard(corpid, userVo, jsonObject, paasFormData);
        }
    }


    /**
     * 获取用户和权限信息
     * @param corpid
     * @param userId
     * @return
     * @throws XbbException
     * 创建时间 2021/5/31 9:17 AM
     * 修改时间 2021/5/31 9:17 AM
     * @author chy
     */
    private UserVO getUserVO(String corpid, String userId) throws XbbException {
        UserInfoDTO userInfoDTO = new UserInfoDTO();
        userInfoDTO.setCorpid(corpid);
        userInfoDTO.setUserId(userId);
        userInfoDTO.setPlatform(PlatFormEnum.INTERNAL.getValue());
        userInfoDTO.setPaasPermissionsFlag(true);
        userInfoDTO.setUserDetailFlag(true);
        userInfoDTO.setCompanyInfoFlag(false);
        Locale locale = LocaleContextHolder.getLocale();
        String lang = locale.toString();
        XbbResponse<UserInfoVO> userInfoResp = connectionUserFeignClient.getUserInfo(userInfoDTO, lang);
        if (userInfoResp.isSuccess()) {
            UserInfoVO userInfo = userInfoResp.getResult();
            return userInfo.getUser();
        } else {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100004.getCode(), "用户不存在，corpid:" + corpid + " userId:" + userId);
        }
    }

    /**
     * 获取存在数据库中的实体
     * @param corpid
     * @param jsonObject
     * @return
     */
    protected abstract PaasFormDataEntityExt getEntity(String corpid, JSONObject jsonObject) throws XbbException;

    /**
     * 新增
     * @param corpid
     * @param userVo
     * @param jsonObject
     */
    protected abstract void addStandard(String corpid, UserVO userVo, JSONObject jsonObject) throws XbbException;

    /**
     * 编辑
     * @param corpid
     * @param userVo
     * @param jsonObject
     * @param paasFormData
     */
    protected abstract void updateStandard(String corpid, UserVO userVo, JSONObject jsonObject, PaasFormDataEntityExt paasFormData) throws XbbException;

    /**
     * 删除
     * @param jsonObject
     */
    protected void deleteStandard(JSONObject jsonObject) throws XbbException {
        ActionBasePojo actionBasePojo = jsonObject.toJavaObject(ActionBasePojo.class);
        String corpid = actionBasePojo.getDdDataCorpId();
        String operateUserId = actionBasePojo.getOperateUserId();
        UserVO userVo = getUserVO(corpid, operateUserId);
        deleteCore(userVo, jsonObject);
    }

    /**
     * 删除的核心逻辑
     * @param userVo
     * @param jsonObject
     */
    protected abstract void deleteCore(UserVO userVo, JSONObject jsonObject) throws XbbException;


    /**
     * 通过编码获取客户
     * @param corpid
     * @param serialNo
     * @return
     * @throws XbbException
     * 创建时间 2021/10/22 10:56 AM
     * 修改时间 2021/10/22 10:56 AM
     * @author chy
     */
    public PaasFormDataEntityExt getCustomerBySerialNo(String corpid, String serialNo) throws XbbException {
        BoolQueryBuilder boolQueryBuilder = boolQuery();
        boolQueryBuilder.filter(termQuery("corpid.keyword", corpid));
        boolQueryBuilder.filter(termQuery(BasicConstant.SERIAL_NO + ".keyword", serialNo));
        boolQueryBuilder.filter(termQuery(StringConstant.DEL, DelEnum.NORMAL.getDel()));
        List<String> fieldList = new ArrayList<>();
        fieldList.add(StringConstant.DATA_ID);
        fieldList.add(StringConstant.CORPID);
        fieldList.add("serialNo");
        fieldList.add("appId");
        fieldList.add("menuId");
        fieldList.add("formId");
        fieldList.add("updateTime");
        fieldList.add(CustomerManagementEnum.getAttrConnectData(CustomerManagementEnum.NAME));
        IndexTypeEnum indexTypeEnum = indexTypeModel.getCustomerIndex(corpid, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), SaasMarkEnum.SAAS.getCode());
        List<PaasFormDataEntityExt> paasFormDataEntityExtList = esHelper.findByScroll(indexTypeEnum,boolQueryBuilder,PaasFormDataEntityExt.class,fieldList);
        LOG.info("paasFormDataEntityExtList:" + paasFormDataEntityExtList.size());
        return paasFormDataEntityExtList.isEmpty() ? null : paasFormDataEntityExtList.get(0);
    }

    /**
     * 通过编码获取销售机会
     * @param corpid
     * @param serialNo
     * @return
     * @throws XbbException
     * 创建时间 2021/10/22 10:56 AM
     * 修改时间 2021/10/22 10:56 AM
     * @author chy
     */
    public PaasFormDataEntityExt getOpportunityBySerialNo(String corpid, String serialNo) throws XbbException {
        BoolQueryBuilder boolQueryBuilder = boolQuery();
        boolQueryBuilder.filter(termQuery("corpid.keyword", corpid));
        boolQueryBuilder.filter(termQuery(BasicConstant.SERIAL_NO + ".keyword", serialNo));
        boolQueryBuilder.filter(termQuery(StringConstant.DEL, DelEnum.NORMAL.getDel()));
        List<String> fieldList = new ArrayList<>();
        fieldList.add(StringConstant.DATA_ID);
        fieldList.add(StringConstant.CORPID);
        fieldList.add("serialNo");
        fieldList.add("appId");
        fieldList.add("menuId");
        fieldList.add("formId");
        fieldList.add("updateTime");
        fieldList.add(SalesOpportunityEnum.getAttrConnectData(SalesOpportunityEnum.NAME));
        List<PaasFormDataEntityExt> paasFormDataEntityExtList = esHelper.findByScroll(IndexTypeEnum.IDX_SAAS_OPPORTUNITY,boolQueryBuilder,PaasFormDataEntityExt.class,fieldList);
        LOG.info("paasFormDataEntityExtList:" + paasFormDataEntityExtList.size());
        return paasFormDataEntityExtList.isEmpty() ? null : paasFormDataEntityExtList.get(0);
    }

    /**
     * 通过编码获取合同订单
     * @param corpid
     * @param serialNo
     * @return
     * @throws XbbException
     * 创建时间 2021/10/22 10:56 AM
     * 修改时间 2021/10/22 10:56 AM
     * @author chy
     */
    public PaasFormDataEntityExt getContractBySerialNo(String corpid, String serialNo) throws XbbException {
        BoolQueryBuilder boolQueryBuilder = boolQuery();
        boolQueryBuilder.filter(termQuery("corpid.keyword", corpid));
        boolQueryBuilder.filter(termQuery(BasicConstant.SERIAL_NO + ".keyword", serialNo));
        boolQueryBuilder.filter(termQuery(StringConstant.DEL, DelEnum.NORMAL.getDel()));
        List<String> fieldList = new ArrayList<>();
        fieldList.add(StringConstant.DATA_ID);
        fieldList.add(StringConstant.CORPID);
        fieldList.add("serialNo");
        fieldList.add("appId");
        fieldList.add("menuId");
        fieldList.add("formId");
        fieldList.add("updateTime");
        fieldList.add(ContractEnum.getAttrConnectData(ContractEnum.NAME));
        List<PaasFormDataEntityExt> paasFormDataEntityExtList = esHelper.findByScroll(IndexTypeEnum.IDX_SAAS_OPPORTUNITY,boolQueryBuilder,PaasFormDataEntityExt.class,fieldList);
        LOG.info("paasFormDataEntityExtList:" + paasFormDataEntityExtList.size());
        return paasFormDataEntityExtList.isEmpty() ? null : paasFormDataEntityExtList.get(0);
    }
}
